package handler

import (
	"admin-nexus-backend/internal/dto"
	"admin-nexus-backend/internal/service"
	"admin-nexus-backend/pkg/captcha"
	"admin-nexus-backend/pkg/jwt"
	"admin-nexus-backend/pkg/response"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type AuthHandler struct {
	userService *service.UserService
}

func NewAuthHandler(db *gorm.DB) *AuthHandler {
	return &AuthHandler{
		userService: service.NewUserService(db),
	}
}

// GetCaptcha 获取验证码
// @Summary 获取验证码
// @Description 获取图片验证码
// @Tags 认证
// @Produce json
// @Success 200 {object} response.Response{data=dto.CaptchaResponse}
// @Router /api/v1/auth/captcha [get]
func (h *AuthHandler) GetCaptcha(c *gin.Context) {
	// 使用字符串验证码，包含数字和字母
	id, b64s, err := captcha.GenerateStringCaptcha()
	if err != nil {
		response.Error(c, "生成验证码失败")
		return
	}

	response.SuccessWithData(c, &dto.CaptchaResponse{
		CaptchaID:    id,
		CaptchaImage: b64s,
	})
}

// Login 用户登录
// @Summary 用户登录
// @Description 用户登录接口
// @Tags 认证
// @Accept json
// @Produce json
// @Param req body dto.LoginRequest true "登录信息"
// @Success 200 {object} response.Response{data=dto.LoginResponse}
// @Router /api/v1/auth/login [post]
func (h *AuthHandler) Login(c *gin.Context) {
	var req dto.LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, err.Error())
		return
	}
	println(req.CaptchaID, req.CaptchaCode)
	// 验证验证码
	if !captcha.VerifyCaptcha(req.CaptchaID, req.CaptchaCode) {
		response.Error(c, "验证码错误")
		return
	}

	// 登录验证
	user, err := h.userService.Login(&req)
	if err != nil {
		response.Error(c, err.Error())
		return
	}

	// 生成 JWT Token
	token, err := jwt.GenerateToken(user.ID, user.Username)
	if err != nil {
		response.Error(c, "生成令牌失败")
		return
	}

	// TODO: 记录登录日志

	response.SuccessWithData(c, &dto.LoginResponse{
		Token: token,
	})
}

// Logout 用户登出
// @Summary 用户登出
// @Description 用户登出接口
// @Tags 认证
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} response.Response
// @Router /api/v1/auth/logout [post]
func (h *AuthHandler) Logout(c *gin.Context) {
	// TODO: 清除 Redis 中的 Token（如果使用 Redis 存储 Token）
	response.SuccessWithMessage(c, "登出成功")
}

// RefreshToken 刷新令牌
// @Summary 刷新令牌
// @Description 刷新 JWT 令牌
// @Tags 认证
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} response.Response{data=dto.LoginResponse}
// @Router /api/v1/auth/refresh [post]
func (h *AuthHandler) RefreshToken(c *gin.Context) {
	userID := c.GetUint("userId")
	username := c.GetString("username")

	// 生成新的 Token
	token, err := jwt.GenerateToken(userID, username)
	if err != nil {
		response.Error(c, "刷新令牌失败")
		return
	}

	response.SuccessWithData(c, &dto.LoginResponse{
		Token: token,
	})
}

// GetUserInfo 获取当前用户信息
// @Summary 获取当前用户信息
// @Description 获取当前登录用户的详细信息
// @Tags 认证
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} response.Response{data=dto.UserInfo}
// @Router /api/v1/auth/userinfo [get]
func (h *AuthHandler) GetUserInfo(c *gin.Context) {
	userID := c.GetUint("userId")

	user, err := h.userService.GetUserByID(userID)
	if err != nil {
		response.Error(c, "获取用户信息失败")
		return
	}

	// 构建用户信息
	userInfo := &dto.UserInfo{
		ID:       user.ID,
		Username: user.Username,
		Nickname: user.Nickname,
		Email:    user.Email,
		Phone:    user.Phone,
		Avatar:   user.Avatar,
		Gender:   user.Gender,
		Status:   user.Status,
		Roles:    make([]string, 0),
	}

	// 获取角色列表
	for _, role := range user.Roles {
		userInfo.Roles = append(userInfo.Roles, role.Code)
	}

	response.SuccessWithData(c, userInfo)
}

// GetUserMenus 获取当前用户菜单
// @Summary 获取当前用户菜单
// @Description 获取当前登录用户的菜单列表
// @Tags 认证
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} response.Response{data=[]dto.MenuData}
// @Router /api/v1/auth/menus [get]
func (h *AuthHandler) GetUserMenus(c *gin.Context) {
	userID := c.GetUint("userId")

	menus, err := h.userService.GetUserMenus(userID)
	if err != nil {
		response.Error(c, "获取用户菜单失败")
		return
	}

	response.SuccessWithData(c, menus)
}

// GetUserPermissions 获取当前用户权限
// @Summary 获取当前用户权限
// @Description 获取当前登录用户的权限列表
// @Tags 认证
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} response.Response{data=[]string}
// @Router /api/v1/auth/permissions [get]
func (h *AuthHandler) GetUserPermissions(c *gin.Context) {
	userID := c.GetUint("userId")

	permissions, err := h.userService.GetUserPermissions(userID)
	if err != nil {
		response.Error(c, "获取用户权限失败")
		return
	}

	response.SuccessWithData(c, permissions)
}
